package com.mygame.xinyue.handler;


import com.mygame.common.component.BaseRoute;
import com.mygame.common.component.RequestPacket;
import com.mygame.common.component.annotation.Handler;
import com.mygame.common.component.annotation.Route;
import com.mygame.common.component.annotation.Rpc;
import com.mygame.common.msg.CommandEnum;
import com.mygame.common.msg.ServiceEnum;
import com.mygame.common.protobuf.gameMsg.*;
import com.mygame.message.dispatcher.IGameChannelContext;
import com.mygame.message.msg.IGameMessage;
import com.mygame.message.msg.game.xinyue.*;
import com.mygame.message.nats.NatsMessageContext;
import com.mygame.common.protobuf.ExternalMessage;
import com.mygame.common.protobuf.ExternalMessageUtil;
import com.mygame.xinyue.logic.PlayerLogicHandler;
import com.mygame.xinyue.logic.event.GetArenaPlayerEvent;
import com.mygame.xinyue.logic.event.GetPlayerInfoEvent;
import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.Promise;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Route(serviceType = ServiceEnum.GAME_LOGIC)
public class PlayerHandler implements BaseRoute<RequestPacket> {
    private Logger logger = LoggerFactory.getLogger(PlayerLogicHandler.class);

    @Override
    public void onReceive(RequestPacket packet) {
        System.out.println("CommonHandler");
    }


    //GATE_SERVER.CommonHandler.C2S_TEST
    @Handler(cmd = CommandEnum.C2S_TEST)
    public void C2S_TEST(IGameMessage gameMessage, IGameChannelContext ctx) {
        System.out.println("CommonHandler");
    }

    @Handler(cmd = CommandEnum.C2S_TEST2)
    public void C2S_TEST2(IGameMessage gameMessage, IGameChannelContext ctx) {
        System.out.println("CommonHandler");
    }

    @Handler(cmd = CommandEnum.C2S_IM_SEND)
    public void C2S_IM_SEND(IMSendRequest request, NatsMessageContext ctx) {

    }

    @Handler(cmd = CommandEnum.C2S_ENTER_GAME)
    public void C2S_ENTER_GAME(EnterGameRequest request, NatsMessageContext ctx) {
        EnterGameResponse response = new EnterGameResponse();
        response.setNickname("叶孤城");
        response.setPlayerId(1);
        ExternalMessage message = ExternalMessageUtil.build(CommandEnum.S2C_ENTER_GAME, response);
        ctx.sendMessage(message);
    }

    @Handler(cmd = CommandEnum.C2S_GET_PLAYER_BY_ID)
    public void C2S_GET_PLAYER_BY_ID(GetPlayerByIdRequest request, NatsMessageContext ctx) {
//        long playerId = request.getPlayerId();
        long playerId = ((ExternalMessage) ctx.getRequest()).getPlayerId();
        DefaultPromise<Object> promise = ctx.newPromise();
        GetPlayerInfoEvent event = new GetPlayerInfoEvent(playerId);
//        ctx.sendUserEvent(event, promise, playerId).addListener(new GenericFutureListener<Future<? super Object>>() {
//            @Override
//            public void operationComplete(Future<? super Object> future) throws Exception {
//                if (future.isSuccess()) {
//                    GetPlayerByIdResponse response = (GetPlayerByIdResponse) future.get();
//                    ExternalMessage message = ExternalMessageUtil.build(CommandEnum.S2C_GET_PLAYER_BY_ID, response);
//                    ctx.sendMessage(message);
//                } else {
//                    logger.error("playerId {} 数据查询失败", playerId, future.cause());
//                }
//            }
//        });
        ctx.sendUserEvent(event, promise, playerId).addListener((Future<? super Object> future) -> {
            if (future.isSuccess()) {
                GetPlayerByIdResponse response = (GetPlayerByIdResponse) future.get();
                ExternalMessage message = ExternalMessageUtil.build(CommandEnum.S2C_GET_PLAYER_BY_ID, response);
                ctx.sendMessage(message);
            } else {
                logger.error("playerId {} 数据查询失败", playerId, future.cause());
            }
        });
    }



//    @Rpc(cmd = CommandEnum.C2S_BUY_ARENA_CHALLENGE_TIMES_REQ)
//    public void C2S_BUY_ARENA_CHALLENGE_TIMES(BuyArenaChallengeTimesRequest request, NatsMessageContext ctx) {
//        ConsumeDiamondRequest consumeDiamondMsgRequest = new ConsumeDiamondRequest();
//        Promise<ExternalMessage> promise = ctx.newPromise();
//        promise.addListener(new GenericFutureListener<Future<ExternalMessage>>() {
//            @Override
//            public void operationComplete(Future<ExternalMessage> future) throws Exception {
//                if (future.isSuccess()) {
//                    ExternalMessage rpcResponse = (ExternalMessage) future.get();
//                    if (rpcResponse.getErrorCode() == 0) {
//                        // 如果错码为0，表示扣钻石成功，可以增加挑战次数
//                    }
//                } else {
//                    logger.error("竞技场扣除钻石失败", future.cause());
//                    //向客户端返回错误码
//                }
//            }
//        });
//        ExternalMessage message = ExternalMessageUtil.build(CommandEnum.RPC_CONSUME_DIAMOND_REQ, consumeDiamondMsgRequest);
//        ctx.sendRPCMessage(message, promise);
//    }


    @Rpc(cmd = CommandEnum.C2S_GET_ARENA_PLAYER_LIST)
    public void C2S_GET_ARENA_PLAYER_LIST(GetArenaPlayerListRequest request, NatsMessageContext ctx) {
        List<Long> playerIds = this.getAreanPlayerIdList();// 获取本次要显示的PlayerId
        List<GetArenaPlayerListMsgResponse.ArenaPlayer> arenaPlayers = new ArrayList<>(playerIds.size());
        playerIds.forEach(playerId -> {// 遍历所有的PlayerId，向他们对应的GameChannel发送查询事件
            GetArenaPlayerEvent getArenaPlayerEvent = new GetArenaPlayerEvent(playerId);
            Promise<Object> promise = ctx.newPromise();// 注意，这个promise不能放到for循环外面，一个Promise只能被setSuccess一次。
            ctx.sendUserEvent(getArenaPlayerEvent, promise, playerId).addListener(new GenericFutureListener<Future<? super Object>>() {

                @Override
                public void operationComplete(Future<? super Object> future) throws Exception {
                    if (future.isSuccess()) {// 如果执行成功，获取执行的结果
                        GetArenaPlayerListMsgResponse.ArenaPlayer arenaPlayer = (GetArenaPlayerListMsgResponse.ArenaPlayer) future.get();
                        arenaPlayers.add(arenaPlayer);
                    } else {
                        arenaPlayers.add(null);
                    }
                    if (arenaPlayers.size() == playerIds.size()) {// 如果数量相等，说明所有的事件查询都已执行成功，可以返回给客户端数据了。
                        List<GetArenaPlayerListMsgResponse.ArenaPlayer> result = arenaPlayers.stream().filter(c -> c != null).collect(Collectors.toList());
                        GetPlayerListResponse response = new GetPlayerListResponse();
                        response.getPlayerId().add(1L);
                        ExternalMessage message = ExternalMessageUtil.build(CommandEnum.S2C_GET_ARENA_PLAYER_LIST, response);
                        ctx.sendMessage(message);
                    }
                }
            });
        });
    }


    private List<Long> getAreanPlayerIdList() {
        return Arrays.asList(2L, 3L, 4L);// 模拟竞技场列表playerId
    }

}